<?php
/**
 * 单例模式: 防止外部new对象；防止子类继承；防止克隆。
 */

/**
 * 普通的可以调用的类
 * 先定义一个类,实例化两次,看看是否全等(当两个对象是一个的时候才会全等)
 */
class ObjectA {

}

$objA1 = new ObjectA();
$objA2 = new ObjectA();
var_dump($objA1 === $objA2); //bool(false)

/**
 * 私有化构造函数
 */
class ObjectB {
    private static $instance = null;

    public static function getInstance() {
        if (self::$instance === null) {
            //把自身对象赋给一个自己的静态属性
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {

    }
}

$objB1 = ObjectB::getInstance();
$objB2 = ObjectB::getInstance();
var_dump($objB1 === $objB2); //bool(true)

//但是对其中一个实例进行克隆之后,判断全等还是false
$objB3 = clone $objB1;
var_dump($objB1 === $objB3); //bool(false)

/**
 * 私有化构造函数 && 禁止克隆
 */
class ObjectC {
    private static $instance = null;

    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    //私有化构造函数
    private function __construct() {

    }

    //禁止克隆
    private function __clone() {

    }
}

$objC1 = ObjectC::getInstance();
$objC2 = ObjectC::getInstance();
var_dump($objC1 === $objC2); //bool(true)

$objC3 = clone $objC1; //此处报错:Fatal error: Uncaught Error: Call to private ObjectC::__clone() from context ''
var_dump($objC1 === $objC3); //程序不会执行到这里